package com.misalen.retrofit;

import java.lang.annotation.Annotation;
import java.lang.reflect.Type;

import org.json.JSONObject;

import com.google.gson.Gson;
import com.google.gson.TypeAdapter;
import com.google.gson.reflect.TypeToken;
import com.misalen.retrofit.converter.request.GsonRequestBodyConverter;
import com.misalen.retrofit.converter.request.JsonRequestBodyConverter;
import com.misalen.retrofit.converter.response.GsonResponseBodyConverter;
import com.misalen.retrofit.converter.response.JsonResponseBodyConverter;

import okhttp3.RequestBody;
import okhttp3.ResponseBody;
import retrofit2.Converter;
import retrofit2.Retrofit;

public final class RetrofitConverterFactory extends Converter.Factory {

	public static RetrofitConverterFactory create() {
		return create(new Gson());
	}

	public static RetrofitConverterFactory create(Gson gson) {
		return new RetrofitConverterFactory(gson);
	}

	private final Gson gson;

	private RetrofitConverterFactory(Gson gson) {
		if (gson == null)
			throw new NullPointerException("gson == null");
		this.gson = gson;
	}

	@Override
	public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
		TypeToken<?> typeToken = TypeToken.get(type);
		if (typeToken.getRawType().getName().equals(JSONObject.class.getName())) {
			return new JsonResponseBodyConverter();
		} else {
			TypeAdapter<?> adapter = gson.getAdapter(typeToken);
			return new GsonResponseBodyConverter<>(adapter);
		}
	}

	@Override
	public Converter<?, RequestBody> requestBodyConverter(Type type, Annotation[] parameterAnnotations,
			Annotation[] methodAnnotations, Retrofit retrofit) {
		TypeToken<?> typeToken = TypeToken.get(type);
		if (typeToken.getRawType().getName().equals(JSONObject.class.getName())) {
			return new JsonRequestBodyConverter();
		} else {
			TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
			return new GsonRequestBodyConverter<>(gson, adapter);
		}

	}
}
